package evolution.operation.migration;

import java.util.List;

import evolution.executor.EvolutionaryAlghorithmEpochRunner;
import evolution.individual.Individual;
import evolution.individual.IndividualSorter;

public class MigrationHelper {
	public static void replaceLastN(Individual[] best,
			Individual[] targetPopulation, int count) {
		replaceLastN(best, targetPopulation, count, 0);
	}

	public static void replaceLastN(Individual[] best,
			Individual[] targetPopulation, int n, int worstIndexOffset) {
		int targetLength = targetPopulation.length;
		int targetBeginIndex = targetLength - n - worstIndexOffset;

		for (int i = 0; i < n; i++) {
			targetPopulation[targetBeginIndex + i] = best[i].clone();
		}
	}

	public static Individual[][] extractPopulations(
			List<EvolutionaryAlghorithmEpochRunner> evolutionaryAlghorithmEpochRunners) {
		int size = evolutionaryAlghorithmEpochRunners.size();
		Individual[][] populations = new Individual[size][];

		for (int i = 0; i < size; i++) {
			populations[i] = evolutionaryAlghorithmEpochRunners.get(i)
					.getEvolutionaryAlghorithm().getPopulation();
		}

		return populations;
	}

	public static Individual[][] buildBestIndividualsLists(
			Individual[][] populations, int migrationSize) {
		int size = populations.length;
		Individual[][] allBest = new Individual[size][];

		for (int i = 0; i < size; i++) {
			Individual[] population = populations[i];
			allBest[i] = getNBest(population, migrationSize);
		}

		return allBest;
	}

	/**
	 * Note: performs population sorting from best to worst
	 * 
	 * @param population
	 * @param n
	 * @return n best individuals
	 */
	public static Individual[] getNBest(Individual[] population, int n) {
		IndividualSorter.sort(population);
		Individual[] best = new Individual[n];
		System.arraycopy(population, 0, best, 0, n);
		return best;
	}
}
